home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / netlib / RCS / Net_InetHdrChecksum.c,v < prev    next >
Text File  |  1990-01-24  |  8KB  |  421 lines

  1. head     1.4;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.4
  10. date     90.01.24.11.53.42;  author jhh;  state Exp;
  11. branches ;
  12. next     1.3;
  13.  
  14. 1.3
  15. date     89.06.19.14.14.32;  author jhh;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     89.03.23.10.17.51;  author brent;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     88.11.21.09.10.17;  author mendel;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @Formed from net.c of src/lib/old/net.c.
  32. @
  33.  
  34.  
  35. 1.4
  36. log
  37. @Backed out version 1.3 because it doesn't work.
  38. @
  39. text
  40. @/* 
  41.  * Net_InetChecksum2.c --
  42.  *
  43.  *    Compute an internet checksum, including the header.
  44.  *
  45.  * Copyright 1987 Regents of the University of California
  46.  * All rights reserved.
  47.  * Permission to use, copy, modify, and distribute this
  48.  * software and its documentation for any purpose and without
  49.  * fee is hereby granted, provided that the above copyright
  50.  * notice appear in all copies.  The University of California
  51.  * makes no representations about the suitability of this
  52.  * software for any purpose.  It is provided "as is" without
  53.  * express or implied warranty.
  54.  */
  55.  
  56. #ifndef lint
  57. static char rcsid[] = "$Header: /sprite/src/lib/net/RCS/Net_InetHdrChecksum.c,v 1.2 89/03/23 10:17:51 brent Exp $ SPRITE (Berkeley)";
  58. #endif not lint
  59.  
  60.  
  61. #include "sprite.h"
  62. #include "net.h"
  63.  
  64. /*
  65.  *----------------------------------------------------------------------
  66.  *
  67.  * Net_InetChecksum2 --
  68.  *
  69.  *    This routine is an optimization for calculating checksums for
  70.  *    the UDP and TCP output routines. It is similar to Net_InetChecksum 
  71.  *    except the checksum includes the IP pseudo-header.
  72.  *
  73.  *    The comments of Net_InetChecksum apply here.
  74.  *
  75.  * Results:
  76.  *    The 1's complement checksum in network byte-order.
  77.  *
  78.  * Side effects:
  79.  *    None.
  80.  *
  81.  *----------------------------------------------------------------------
  82.  */
  83.  
  84. unsigned short
  85. Net_InetChecksum2(len, bufPtr, pseudoHdrPtr)
  86.     register int     len;        /* The # of bytes in bufPer. */
  87.     Address        bufPtr;        /* Data to checksum. */
  88.     Net_IPPseudoHdr    *pseudoHdrPtr;    /* IP pseudo-header to include in the
  89.                      * checksum. */
  90. {
  91.     register unsigned short *wordPtr;
  92.     register unsigned int sum = 0;
  93.  
  94.  
  95.     /*
  96.      * First compute the checksum for the IP pseudo-header.
  97.      */
  98.     wordPtr = (unsigned short *) pseudoHdrPtr;
  99.     if (sizeof(*pseudoHdrPtr) == 20) {
  100.     /*
  101.      * This is a hack because cpp can't use the sizeof operator 
  102.      * in #if statements.
  103.      */
  104.     sum += *wordPtr++;
  105.     sum += *wordPtr++;
  106.     sum += *wordPtr++;
  107.     sum += *wordPtr++;
  108.     sum += *wordPtr++;
  109.  
  110.     sum += *wordPtr++;
  111.     sum += *wordPtr++;
  112.     sum += *wordPtr++;
  113.     sum += *wordPtr++;
  114.     sum += *wordPtr++;
  115.  
  116.     } else {
  117.     register int i;
  118.  
  119.     i = sizeof(*pseudoHdrPtr)/sizeof(unsigned short);
  120.     do {
  121.         sum += *wordPtr++;
  122.         i--;
  123.     } while (i > 0);
  124.     }
  125.  
  126.     /*
  127.      * Sum the data in an unrolled loop. Once we have less than 
  128.      * 32 bytes to sum then it must be done in smaller loops.
  129.      */
  130.  
  131.     wordPtr = (unsigned short *) bufPtr;
  132.     while (len >= 32) {
  133.     sum += *wordPtr++;
  134.     sum += *wordPtr++;
  135.     sum += *wordPtr++;
  136.     sum += *wordPtr++;
  137.  
  138.     sum += *wordPtr++;
  139.     sum += *wordPtr++;
  140.     sum += *wordPtr++;
  141.     sum += *wordPtr++;
  142.  
  143.     sum += *wordPtr++;
  144.     sum += *wordPtr++;
  145.     sum += *wordPtr++;
  146.     sum += *wordPtr++;
  147.  
  148.     sum += *wordPtr++;
  149.     sum += *wordPtr++;
  150.     sum += *wordPtr++;
  151.     sum += *wordPtr++;
  152.  
  153.     len -= 32;
  154.     }
  155.     while (len >= 2) {
  156.     sum += *wordPtr++;
  157.     len -= 2;
  158.     }
  159.  
  160.     if (len == 1) {
  161. #if BYTE_ORDER == LITTLE_ENDIAN
  162.     sum += (*wordPtr) & 0x00ff;
  163. #else
  164.     sum += (*wordPtr) & 0xff00;
  165. #endif
  166.     }
  167.  
  168.     /*
  169.      * The most signficant bits of "sum" contains the carries from
  170.      * the overflow of the summing. Add this overflow back into
  171.      * the least significant 16 bits of the sum and do it a second
  172.      * time in case there's a carry from the first time.
  173.      */
  174.     if (sum > 0xffff) {
  175.     sum = ((sum >> 16) & 0xffff) + (sum & 0xffff);
  176.  
  177.     /*
  178.      * See if there was a carry from the addition. The overflow will
  179.      * be at most 1.
  180.      */
  181.     if (sum > 0xffff) {
  182.         sum++;
  183.     }
  184.     }
  185.  
  186.     return((~sum & 0xffff));
  187. }
  188.  
  189. @
  190.  
  191.  
  192. 1.3
  193. log
  194. @Allow buffers to be odd-aligned
  195. @
  196. text
  197. @a35 4
  198.  *    We have to compute the two checksums separately because one buffer
  199.  *    may be word aligned and one not. After we compute them we add them
  200.  *    together and do the usual manipulation of the carry bits.
  201.  *
  202. d53 1
  203. a53 9
  204.     register unsigned int sum1 = 0;
  205.     register unsigned int sum2 = 0;
  206.     int        pseudoLen;
  207.     int        sum;
  208.  
  209.     union {
  210.     unsigned char    c[2];        /* data as bytes */
  211.     unsigned short    s;        /* data as a word */
  212.     } convert;
  213. a54 1
  214.     Boolean oddAligned = FALSE;
  215. d60 1
  216. a60 11
  217.     convert.s = 0;
  218.     pseudoLen = sizeof(*pseudoHdrPtr);
  219.  
  220.     if (((int) wordPtr & 1)) {
  221.     convert.c[1] = *(unsigned char *) wordPtr;
  222.     wordPtr = (unsigned short *) ((char *) wordPtr + 1);
  223.     oddAligned = TRUE;
  224.     pseudoLen -= 1;
  225.     }
  226.  
  227.     if (pseudoLen == 20) {
  228. d65 11
  229. a75 11
  230.     sum1 += *wordPtr++;
  231.     sum1 += *wordPtr++;
  232.     sum1 += *wordPtr++;
  233.     sum1 += *wordPtr++;
  234.     sum1 += *wordPtr++;
  235.  
  236.     sum1 += *wordPtr++;
  237.     sum1 += *wordPtr++;
  238.     sum1 += *wordPtr++;
  239.     sum1 += *wordPtr++;
  240.     sum1 += *wordPtr++;
  241. d78 7
  242. a84 15
  243.     while (pseudoLen >= 2) {
  244.         sum1 += *wordPtr++;
  245.         pseudoLen -= 2;
  246.     }
  247.     }
  248.     if (pseudoLen == 1) {
  249.     convert.c[0] = *((unsigned char *) wordPtr);
  250.     }
  251.     sum1 += convert.s;
  252.     convert.s = 0;
  253.     if (sum1 > 0xffff) {
  254.     sum1 = ((sum1 >> 16) & 0xffff) + (sum1 & 0xffff);
  255.     if (sum1 > 0xffff) {
  256.         sum1++;
  257.     }
  258. a85 3
  259.     if (oddAligned) {
  260.     sum1 = (sum1 >> 8) | ((sum1 & 0xff) << 8);
  261.     }
  262. d91 1
  263. a92 11
  264.     convert.s = 0;
  265.  
  266.     if (((int) wordPtr & 1)) {
  267.     convert.c[1] = *(unsigned char *) wordPtr;
  268.     wordPtr = (unsigned short *) ((char *) wordPtr + 1);
  269.     oddAligned = TRUE;
  270.     len -= 1;
  271.     } else {
  272.     oddAligned = FALSE;
  273.     }
  274.  
  275. d94 4
  276. a97 4
  277.     sum2 += *wordPtr++;
  278.     sum2 += *wordPtr++;
  279.     sum2 += *wordPtr++;
  280.     sum2 += *wordPtr++;
  281. d99 14
  282. a112 14
  283.     sum2 += *wordPtr++;
  284.     sum2 += *wordPtr++;
  285.     sum2 += *wordPtr++;
  286.     sum2 += *wordPtr++;
  287.  
  288.     sum2 += *wordPtr++;
  289.     sum2 += *wordPtr++;
  290.     sum2 += *wordPtr++;
  291.     sum2 += *wordPtr++;
  292.  
  293.     sum2 += *wordPtr++;
  294.     sum2 += *wordPtr++;
  295.     sum2 += *wordPtr++;
  296.     sum2 += *wordPtr++;
  297. d117 1
  298. a117 1
  299.     sum2 += *wordPtr++;
  300. d122 5
  301. a126 1
  302.     convert.c[0] = *((unsigned char *) wordPtr);
  303. a127 1
  304.     sum2 += convert.s;
  305. d135 2
  306. a136 2
  307.     if (sum2 > 0xffff) {
  308.     sum2 = ((sum2 >> 16) & 0xffff) + (sum2 & 0xffff);
  309. a141 10
  310.     if (sum2 > 0xffff) {
  311.         sum2++;
  312.     }
  313.     }
  314.     if (oddAligned) {
  315.     sum2 = (sum2 >> 8) | ((sum2 & 0xff) << 8);
  316.     }
  317.     sum = sum1 + sum2;
  318.     if (sum > 0xffff) {
  319.     sum = ((sum >> 16) & 0xffff) + (sum & 0xffff);
  320. @
  321.  
  322.  
  323. 1.2
  324. log
  325. @Fixed LITTLE_ENDIAN check.  It has to be
  326. #if BYTE_ORDER == LITTLE_ENDIAN
  327. and it cannot be
  328. #ifdef LITTLE_ENDIAN
  329. @
  330. text
  331. @d18 1
  332. a18 1
  333. static char rcsid[] = "$Header: /sprite/src/lib/net/RCS/Net_InetHdrChecksum.c,v 1.1 88/11/21 09:10:17 mendel Exp $ SPRITE (Berkeley)";
  334. d36 4
  335. d57 9
  336. a65 1
  337.     register unsigned int sum = 0;
  338. d67 1
  339. d73 11
  340. a83 1
  341.     if (sizeof(*pseudoHdrPtr) == 20) {
  342. d88 11
  343. a98 11
  344.     sum += *wordPtr++;
  345.     sum += *wordPtr++;
  346.     sum += *wordPtr++;
  347.     sum += *wordPtr++;
  348.     sum += *wordPtr++;
  349.  
  350.     sum += *wordPtr++;
  351.     sum += *wordPtr++;
  352.     sum += *wordPtr++;
  353.     sum += *wordPtr++;
  354.     sum += *wordPtr++;
  355. d101 18
  356. a118 7
  357.     register int i;
  358.  
  359.     i = sizeof(*pseudoHdrPtr)/sizeof(unsigned short);
  360.     do {
  361.         sum += *wordPtr++;
  362.         i--;
  363.     } while (i > 0);
  364. d125 2
  365. d128 9
  366. a136 1
  367.     wordPtr = (unsigned short *) bufPtr;
  368. d138 4
  369. a141 4
  370.     sum += *wordPtr++;
  371.     sum += *wordPtr++;
  372.     sum += *wordPtr++;
  373.     sum += *wordPtr++;
  374. d143 14
  375. a156 14
  376.     sum += *wordPtr++;
  377.     sum += *wordPtr++;
  378.     sum += *wordPtr++;
  379.     sum += *wordPtr++;
  380.  
  381.     sum += *wordPtr++;
  382.     sum += *wordPtr++;
  383.     sum += *wordPtr++;
  384.     sum += *wordPtr++;
  385.  
  386.     sum += *wordPtr++;
  387.     sum += *wordPtr++;
  388.     sum += *wordPtr++;
  389.     sum += *wordPtr++;
  390. d161 1
  391. a161 1
  392.     sum += *wordPtr++;
  393. d166 1
  394. a166 5
  395. #if BYTE_ORDER == LITTLE_ENDIAN
  396.     sum += (*wordPtr) & 0x00ff;
  397. #else
  398.     sum += (*wordPtr) & 0xff00;
  399. #endif
  400. d168 1
  401. d176 2
  402. a177 2
  403.     if (sum > 0xffff) {
  404.     sum = ((sum >> 16) & 0xffff) + (sum & 0xffff);
  405. d183 10
  406. @
  407.  
  408.  
  409. 1.1
  410. log
  411. @Initial revision
  412. @
  413. text
  414. @d18 1
  415. a18 1
  416. static char rcsid[] = "$Header: net.c,v 2.0 87/08/11 09:34:20 brent Exp $ SPRITE (Berkeley)";
  417. d122 1
  418. a122 1
  419. #ifdef LITTLE_ENDIAN
  420. @
  421.